package lt.hsu.product.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import lt.hsu.product.entities.ProductEntity;
import lt.hsu.product.service.IProductService;
import lt.hsu.product.thr.ProductError;
import lt.hsu.product.vo.ProductInfoRes;
import lt.hsu.product.vo.convert.ProductReqToEntity;
import lt.hsu.product.vo.req.AddProductReq;
import lt.hsu.product.vo.req.DelProductReq;
import lt.hsu.product.vo.req.QueryProductReq;
import lt.hsu.product.vo.req.UpdateProductReq;
import lt.hsu.steam.SteamKit;
import lt.hsu.web.EApiReturn;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@Slf4j
@Validated
@Tag(name = "产品API", description = "Product API")
public class ProductController {

    @Resource
    private IProductService productService;

    @PostMapping("product/list")
    @Operation(description = "获取产品列表")
    public IPage<ProductInfoRes> getProductList(@RequestBody QueryProductReq req) {
        return productService.lambdaQuery()
                .like(req.isNameLike(), ProductEntity::getName, req.getProductName())
                .eq(StringUtils.isNotBlank(req.getProductCode()), ProductEntity::getCode, req.getProductCode())
                .page(req.toPage())
                .convert(ProductReqToEntity::convert);
    }

    // 添加新产品
    @PostMapping("product/add")
    @Operation(description = "添加新产品")
    @Transactional
    public String addProduct(@RequestBody AddProductReq req) {
        boolean exists = productService.lambdaQuery()
                .eq(ProductEntity::getCode, req.getProductCode())
                .exists();
        if (exists) {
            throw ProductError.PRODUCT_EXISTS.toThr();
        }

        // 添加产品
        ProductEntity convert = ProductReqToEntity.convert(req);
        boolean save = productService.save(convert);
        if (!save) {
            throw ProductError.SAVE_PRODUCT_FAILURE.toThr();
        }
        return "success";
    }

    @PostMapping("product/del")
    @Operation(description = "删除产品")
    @Transactional
    public List<String> delProduct(@RequestBody DelProductReq req) {
        boolean exists = productService.lambdaQuery()
                .in(ProductEntity::getCode, req.getProductCode())
                .exists();
        if (!exists) {
            throw ProductError.PRODUCT_NOT_EXISTS.toThr();
        }

        boolean remove = productService.lambdaUpdate()
                .in(ProductEntity::getCode, req.getProductCode())
                .remove();
        // 添加产品
        if (!remove) {
            throw ProductError.SAVE_PRODUCT_FAILURE.toThr();
        }
        List<ProductEntity> deletedProducts = productService.lambdaQuery()
                .in(ProductEntity::getCode, req.getProductCode())
                .eq(ProductEntity::getDeleted, 1)
                .list();
        return deletedProducts.stream().map(ProductEntity::getCode).collect(Collectors.toList());
    }

    @PostMapping("product/update")
    @Operation(description = "更新产品")
    @Transactional
    public List<String> updateProduct(@RequestBody List<UpdateProductReq> req) {
        if (req.isEmpty()) {
            throw EApiReturn.FAILURE.toThr();
        }
        List<String> productCodes = SteamKit.toList(req, UpdateProductReq::getProductCode);
        Map<String, String> t = SteamKit.toMap(req, UpdateProductReq::getProductCode, UpdateProductReq::getProductName);
        List<ProductEntity> products = productService.lambdaQuery()
                .in(ProductEntity::getCode, productCodes)
                .list();
        List<ProductEntity> productEntities = products.stream()
                .filter(p -> t.containsValue(p.getName()))
                .peek(p -> p.setName(t.get(p.getCode())))
                .collect(Collectors.toList());
        boolean updateBatchById = productService.updateBatchById(productEntities);
        // 添加产品
        if (!updateBatchById) {
            throw ProductError.UPDATE_PRODUCT_FAILURE.toThr();
        }
        return SteamKit.toList(productEntities, ProductEntity::getCode);
    }


}
